/**
 * 
 */
package com.padbot.qm.client;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.ws.rs.core.Response;

import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.config.ConnectionConfig;
import org.apache.http.conn.routing.HttpRoute;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSONObject;
import com.padbot.qm.exception.SystemException;
import com.padbot.qm.rest.HttpRequestHeader;
import com.padbot.qm.rest.HttpRequestParameter;
import com.padbot.qm.security.RequestSignFactory;
import com.padbot.qm.util.Constants;

/**
 * @author Deng
 *
 */
public final class PadbotHttpClientUtil {
	
	private static Logger logger = LoggerFactory.getLogger(PadbotHttpClientUtil.class);
	
	private static PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
	
	static{
		try{
		//最大连接数
	    cm.setMaxTotal(200);
	    //每个路由的连接数
	    cm.setDefaultMaxPerRoute(cm.getMaxTotal());
	    logger.debug("Initial connection pool...");
//	    HttpHost httphost = new HttpHost(SERVER_ROOT_URL_HOST, Integer.valueOf(SERVER_ROOT_URL_PORT));
//	    cm.setMaxPerRoute(new HttpRoute(httphost), cm.getMaxTotal());
		}catch(Exception e){
			logger.error("初始化连接池失败", e);
		}
	}
	
	private static HttpClient getHttpClient(){
		HttpClient client = HttpClients.custom().setConnectionManager(cm).build();
		return client;
	}
	
	private static StringBuilder buildUrl(String servName, String methodName){
		StringBuilder url = new StringBuilder();
		url.append(Constants.get(Constants.SERVER_ROOT_URL)).append(servName).append(Constants.URL_SEPARATOR).append(methodName);
		return url;
	}
	
	public static JSONObject loginByAccount(JSONObject params) throws Exception{
		String servName = "openfaqserver";
		String methodName = "logIn.action";
		return post(servName, methodName, params);
	}
	
	public static JSONObject loginByQr(JSONObject params) throws Exception{
		String servName = "openfaqserver";
		String methodName = "checkLogin.action";
		return post(servName, methodName, params);
	}
	
	public static JSONObject post(String servName, String methodName, 
			JSONObject params) throws Exception{
		logger.debug("servName:"+servName+",methodName:"+methodName);
		JSONObject jsonObject = buildParam1(params);
		/*StringBuffer stringBuffer = new StringBuffer();
		Iterator<String> iterator = jsonObject.keySet().iterator();
		int i = 0;
        while(iterator.hasNext()){
        	String key = iterator.next();
        	if(i++ == 0){
        		stringBuffer.append(key).append("=").append(jsonObject.getString(key));
        	}else{
        		stringBuffer.append("&").append(key).append("=").append(jsonObject.getString(key));
        	}
        	
        } */
		HttpClient httpClient = getHttpClient();
		Response response = null;
		HttpPost httpPost = new HttpPost(buildUrl(servName, methodName).toString());
		JSONObject obj = null;
		try{
			httpPost.setConfig(getRequestConfig());
	//		HttpRequestParameter httpRequestParameter = buildParam(params);
	//		JSONObject jsonObject = (JSONObject)JSONObject.toJSON(httpRequestParameter);
	//		httpPost.addHeader(HTTP.CONTENT_TYPE, "application/json");
	//		StringEntity se = new StringEntity(jsonString);
	//		se.setContentType("application/json");
	//        se.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));
			List<NameValuePair> list = new ArrayList<NameValuePair>();
			
			Iterator<String> iterator = jsonObject.keySet().iterator();
	        while(iterator.hasNext()){
	        	String key = iterator.next();
	        	list.add(new BasicNameValuePair(key, jsonObject.getString(key)));
	        }
	        if(list.size() > 0){
	        	UrlEncodedFormEntity entity = new UrlEncodedFormEntity(list, "UTF-8");
	        	httpPost.setEntity(entity);
	        }
	//        StringEntity entity = new StringEntity(stringBuffer.toString(), "UTF-8");
	//        httpPost.setEntity(entity);  
	        logger.debug("Call remove server...");
	        HttpResponse httpResponse=httpClient.execute(httpPost);
	        logger.debug("Complete call...");
	        logger.debug("response:"+httpResponse);
	    	String reponseResult=EntityUtils.toString(httpResponse.getEntity());
	    	obj = JSONObject.parseObject(reponseResult);
	    	String messageCode = obj.getString("messageCode");
	    	logger.debug("messageCode:"+messageCode);
	//    	if(!Constants.SUCCESS_CODE.equals(messageCode)){
	//    		throw new SystemException(Constants.get(messageCode));
	//    	}
		}catch(Exception e){
			
		}finally {
			if(httpPost != null){
				httpPost.releaseConnection();
			}
		}
		return obj;
	}
	
	private static RequestConfig getRequestConfig(){
		return RequestConfig.custom().setConnectTimeout(5000).build();
	}
	
	private static JSONObject buildParam1(JSONObject params){
		JSONObject system = new JSONObject();
		if(params==null){
			params=new JSONObject();
		}
		String appkey = Constants.get(Constants.SERVER_SIGN_APPKEY);
		String apptoken = Constants.get(Constants.SERVER_SIGN_APPTOKEN);
		long currentTime = System.currentTimeMillis()/1000;
		String sign = createSign(params, currentTime, appkey, apptoken);
		system.put("time", currentTime);
		system.put("appkey", appkey);
		//system.put("apptoken", apptoken);
		system.put("sign", sign);
		params.put("system", system);
		return params;
	}
	
	private static HttpRequestParameter buildParam(JSONObject params){
		String appkey = Constants.get(Constants.SERVER_SIGN_APPKEY);
		String apptoken = Constants.get(Constants.SERVER_SIGN_APPTOKEN);
		long currentTime = System.currentTimeMillis();
		String sign = createSign(params, currentTime, appkey, apptoken);
		HttpRequestParameter parameter = new HttpRequestParameter(
				new HttpRequestHeader(currentTime+"", appkey, sign), params);
		return parameter;
	}
	
	private static String createSign(JSONObject params, long currentTime, String appkey, String apptoken){
		String sign = null;
		try {
			sign = RequestSignFactory.sign(params, currentTime, appkey, apptoken);
		} catch (Exception e) {
			logger.error("生成签名出错", e);
			throw new SystemException("生成签名出错", e);
		}
		return sign;
	}
}
